package ar.com.jwa.domain;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import ar.com.jwa.commons.architecture.PersistentObject;

@Entity
@Table(name="Games")
public class Game extends PersistentObject {
	
	private Date theDate;
	
	@Transient
	private String result;
	
	private String place;
	
	private Set<User> confirmedPlayers = new HashSet<User>();
	
	private Set<User> refusedPlayers = new HashSet<User>();
	
	private Set<User> invitedPlayers = new HashSet<User>();
	
	private State state;
	
	public Game(Date theDate) {
		super();
		this.theDate = theDate;
		this.state = State.TO_CONFIRM;
	}
	
	public Game() {
		super();
	}

	public Boolean hasConfirmed(User player){
		return this.getConfirmedPlayers().contains(player);
	}
	
	public void removeFromRefusedPlayers(User user){
		if (hasRefused(user)){
			this.getRefusedPlayers().remove(user);
		}
	}
	
	public Boolean hasRefused(User player){
		return this.getRefusedPlayers().contains(player);
	}
	
	public void confirmPlayer(User player){
		this.getConfirmedPlayers().add(player);
	}
	
	public boolean hasPlayer(User player){
		return this.getConfirmedPlayers().contains(player);
	}
	
	
	
	/**
	 * @return the theDate
	 */
	@Column(name="date")
	public Date getTheDate() {
		return theDate;
	}

	/**
	 * @param theDate the theDate to set
	 */
	public void setTheDate(Date theDate) {
		this.theDate = theDate;
	}
	
	
	/**
	 * @return the result
	 */
	@Column(name="result")
	public String getResult() {
		return result;
	}

	/**
	 * @param result the result to set
	 */
	public void setResult(String result) {
		this.result = result;
	}

	/**
	 * @return the state
	 */

	@Column(name = "state")
	public State getState() {
		return state;
	}

	/**
	 * @param state the state to set
	 */
	public void setState(State state) {
		this.state = state;
	}
	
	/**
	 * @return the players
	 */
	
	@ManyToMany(cascade = CascadeType.ALL, fetch = javax.persistence.FetchType.EAGER, targetEntity = User.class)
	@JoinTable(name = "game_confirmed_users", joinColumns = { @JoinColumn(name = "gameId") }, inverseJoinColumns = { @JoinColumn(name = "userId") })
	public Set<User> getConfirmedPlayers() {
		return confirmedPlayers;
	}

	
	/**
	 * @param players the players to set
	 */
	public void setConfirmedPlayers(Set<User> players) {
		this.confirmedPlayers = players;
	}

	/**
	 * @return the discardedPlayers
	 */
	@ManyToMany(cascade = CascadeType.ALL, fetch = javax.persistence.FetchType.LAZY, targetEntity = User.class)
	@JoinTable(name = "game_discarded_users", joinColumns = { @JoinColumn(name = "gameId") }, inverseJoinColumns = { @JoinColumn(name = "userId") })
	public Set<User> getRefusedPlayers() {
		return refusedPlayers;
	}

	/**
	 * @param discardedPlayers the discardedPlayers to set
	 */
	public void setRefusedPlayers(Set<User> discardedPlayers) {
		this.refusedPlayers = discardedPlayers;
	}
	
	/**
	 * @return the invitedPlayers
	 */
	@ManyToMany(cascade = CascadeType.ALL, fetch = javax.persistence.FetchType.EAGER, targetEntity = User.class)
	@JoinTable(name = "game_invited_users", joinColumns = { @JoinColumn(name = "gameId") }, inverseJoinColumns = { @JoinColumn(name = "userId") })
	public Set<User> getInvitedPlayers() {
		return invitedPlayers;
	}
	
	/**
	 * @param invitedPlayers the invitedPlayers to set
	 */
	public void setInvitedPlayers(Set<User> invitedPlayers) {
		this.invitedPlayers = invitedPlayers;
	}

	/**
	 * @return the place
	 */
	@Column(name="place")
	public String getPlace() {
		return place;
	}

	/**
	 * @param place the place to set
	 */
	public void setPlace(String place) {
		this.place = place;
	}
	
}
